# import matplotlib.pyplot as plt
# from collections import OrderedDict
# from matplotlib.backends.backend_pdf import PdfPages
# import re
import matplotlib.pyplot as plt
import networkx as nx

class BaseAlgorithm:
    def __init__(self, algoname):
        self.algoanme = algoname
        pass

class PageRank:
    def __init__(self, algoname = 'pr'):
        BaseAlgorihm.__init__(algoname)

# Get an random graph
def randomGraph(v_num = 12, p = 0.3):
    graph = nx.binomial_graph(v_num, p, directed=True)
    graph.add_edge(1, 0, weight=10)
    for v, d in graph.nodes(data=True):
        d['weight'] = 1.0 / len(graph.nodes())
    for u,v,d in graph.edges(data=True):
        d['weight'] = 1
    raw_graph = graph.copy()
    nx.draw(graph, with_labels=True)
    plt.show()
    # print list(graph.nodes(data=True))
    # print list(graph.edges(data=True))
    # print "#################"
    return graph

graph = randomGraph()
intermediateResult = dict()
msgqueues = [[] for i in range(len(graph.nodes()))]
pro_num = 4
subgraphs = [dict() for i in range(pro_num)]
for i in range(pro_num):
    pass

'''
Define computation work.
parameters:
    msg:
'''
def computing(msgs = None):
    # calculate the pr
    msg_sum = 0.0
    for i, msgqueue in enumerate(msgqueues):
        graph.node[i]['weight'] = 0.15 / len(graph.nodes()) \
                + sum(msgqueue) * 0.85

    # clear the message queues
    for node in graph.nodes():
        msgqueues[node][:] = []

    # generate intermediate results
    for node, d in graph.nodes(data = True):
        if len(graph.out_edges(node)) <= 0:
            continue
        share_pr = d['weight'] / len(graph.out_edges(node))
        for u, v in graph.out_edges(node):
            [v].append(share_pr)
        
    '''
    # send msg to other graph nodes
    for node, d in graph.nodes(data=True):
        if len(graph.out_edges(node)) <= 0:
            continue
        share_pr = d['weight'] / len(graph.out_edges(node))
        for u, v in graph.out_edges(node):
            msgqueues[v].append(share_pr)
    '''

# Display graph pagerank values
def displayPR(graph):
    for v, d in graph.nodes(data = True):
        print str(v) + ":" + str(d['weight'])

'''
For data exchange.
parameters:
    a:
    b:
'''
def dataexchange():
    print "dataexchange..."
    pass

'''
Loop entry.
parameters:
    precision: iterative precision
    round: number of iteration
    delta: delta computing per data exchange
'''
def entry(delta = 1, precision = 0.001, rounds = 40):
    round_num = 0
    loss = 0.0
    while loss < precision and round_num < rounds:
        computing()
        if round_num % delta == 0:
            dataexchange()

        # Take termination condition into consideration 
        round_num += 1
        loss += 0.00001
    pass

'''
verify the result
'''
def evaluate(G):
    # G=nx.binomial_graph(10, 0.3, directed=True)
    layout = nx.spring_layout(G)
    plt.figure(1)
    nx.draw(G, pos=layout, node_color='y')

    pr=nx.pagerank(G,alpha=0.85)
    print(pr)

# Start the program
if __name__ == "__main__":
    displayPR(graph)
    entry(2)
    displayPR(graph)
    print "#############################"
    evaluate(graph)
    pass
